package city.spring.service.mealService.impl;

import city.spring.domain.entity.mealService.FoodInfoEntity;
import city.spring.modules.ext.entity.FoodDiseaseExt;
import city.spring.modules.ext.entity.MealFoodExt;
import city.spring.modules.ext.service.FoodDiseaseExtService;
import city.spring.modules.ext.service.MealFoodExtService;
import city.spring.modules.health.entity.DiseaseEntity;
import city.spring.modules.health.service.DiseaseService;
import city.spring.repository.mealService.FoodInfoRepository;
import city.spring.service.mealService.FoodInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;

@Service
@Transactional(rollbackFor = Throwable.class)
public class FoodInfoServiceImpl extends ServiceImpl<FoodInfoRepository, FoodInfoEntity> implements FoodInfoService {

    private final DiseaseService diseaseService;
    private final FoodDiseaseExtService foodDiseaseExtService;
    private final MealFoodExtService mealFoodExtService;

    public FoodInfoServiceImpl(DiseaseService diseaseService, FoodDiseaseExtService foodDiseaseExtService, MealFoodExtService mealFoodExtService) {
        this.diseaseService = diseaseService;
        this.foodDiseaseExtService = foodDiseaseExtService;
        this.mealFoodExtService = mealFoodExtService;
    }

    @Override
    public void loadDisease(FoodInfoEntity entity) {
        String foodInfoId = entity.getId();
        List<DiseaseEntity> forbiddenEntities = diseaseService.getFoodDisease(foodInfoId, 0);
        List<DiseaseEntity> recommendEntities = diseaseService.getFoodDisease(foodInfoId, 1);
        entity.setForbiddenDisease(forbiddenEntities);
        entity.setRecommendDisease(recommendEntities);
    }

    @Override
    public void loadDisease(List<FoodInfoEntity> entities) {
        entities.forEach(this::loadDisease);
    }

    @Override
    public void setFoodDisease(FoodInfoEntity entity) {
        String foodInfoId = entity.getId();
        List<DiseaseEntity> forbiddenDisease = entity.getForbiddenDisease();
        List<DiseaseEntity> recommendDisease = entity.getRecommendDisease();
        if (forbiddenDisease.size() > 0 && recommendDisease.size() > 0) {
            for (int i = 0; i < forbiddenDisease.size(); i++) {
                for (int j = 0; j < recommendDisease.size(); j++) {
                    if (forbiddenDisease.get(i).equals(recommendDisease.get(j))) {
                        throw new RuntimeException("不适用人群和适用人群不能有交集！");
                    }
                }
            }
        }
        for (int i = 0; i < forbiddenDisease.size(); i++) {
            FoodDiseaseExt ext = new FoodDiseaseExt(null, foodInfoId, forbiddenDisease.get(i).getId(), 0);
            foodDiseaseExtService.save(ext);
        }
        for (int i = 0; i < recommendDisease.size(); i++) {
            FoodDiseaseExt ext = new FoodDiseaseExt(null, foodInfoId, recommendDisease.get(i).getId(), 1);
            foodDiseaseExtService.save(ext);
        }
    }

    @Override
    public void updateFoodDisease(FoodInfoEntity entity) {
        String foodInfoId = entity.getId();
        this.deleteFoodDisease(entity);
        List<DiseaseEntity> forbiddenDisease = entity.getForbiddenDisease();
        List<DiseaseEntity> recommendDisease = entity.getRecommendDisease();
        if (forbiddenDisease.size() > 0 && recommendDisease.size() > 0) {
            for (int i = 0; i < forbiddenDisease.size(); i++) {
                for (int j = 0; j < recommendDisease.size(); j++) {
                    if (forbiddenDisease.get(i).equals(recommendDisease.get(j))) {
                        throw new RuntimeException("不适用人群和适用人群不能有交集！");
                    }
                }
            }
        }
        for (int i = 0; i < forbiddenDisease.size(); i++) {
            FoodDiseaseExt ext = new FoodDiseaseExt(null, foodInfoId, forbiddenDisease.get(i).getId(), 0);
            foodDiseaseExtService.save(ext);
        }
        for (int i = 0; i < recommendDisease.size(); i++) {
            FoodDiseaseExt ext = new FoodDiseaseExt(null, foodInfoId, recommendDisease.get(i).getId(), 1);
            foodDiseaseExtService.save(ext);
        }

    }

    @Override
    public void deleteFoodDisease(FoodInfoEntity entity) {
        String foodInfoId = entity.getId();
        List<FoodDiseaseExt> exts = foodDiseaseExtService.getFoodDiseaseExt(foodInfoId);
        for (int i = 0; i < exts.size(); i++) {
            foodDiseaseExtService.lambdaUpdate().eq(FoodDiseaseExt::getFoodInfoId, foodInfoId).remove();
        }
    }

    @Override
    public void saveFoodInfo(FoodInfoEntity entity) {
        boolean save = save(entity);
        setFoodDisease(entity);
        if (!save) {
            throw new RuntimeException("保存失败！");
        }
    }

    @Override
    public void updateFoodInfo(FoodInfoEntity entity) {
        boolean update = lambdaUpdate()
                .set(FoodInfoEntity::getFoodId, entity.getFoodId())
                .set(FoodInfoEntity::getFoodName, entity.getFoodName())
                .set(FoodInfoEntity::getFoodPrize, entity.getFoodPrize())
                .set(FoodInfoEntity::getHot, entity.getHot())
                .set(FoodInfoEntity::getTexture, entity.getTexture())
                .set(FoodInfoEntity::getTaste, entity.getTaste())
                .set(FoodInfoEntity::isDistribution, entity.isDistribution())
                .set(FoodInfoEntity::getStartTime, entity.getStartTime())
                .set(FoodInfoEntity::getEndTime, entity.getEndTime())
                .set(FoodInfoEntity::getRemarks, entity.getRemarks())
                .eq(FoodInfoEntity::getId, entity.getId())
                .update();
        updateFoodDisease(entity);
        if (!update) {
            throw new RuntimeException("保存失败！");
        }
    }

    @Override
    public void deleteFoodInfo(String primaryKey) {
        removeById(primaryKey);
        deleteFoodDisease(this.getById(primaryKey));
        mealFoodExtService.lambdaUpdate().in(MealFoodExt::getRelatedId, primaryKey).remove();
    }

    @Override
    public void deleteFoodInfo(List<String> primaryKeys) {
        removeByIds(primaryKeys);
        for (int i = 0; i < primaryKeys.size(); i++) {
            deleteFoodDisease(this.getById(primaryKeys.get(i)));
        }
        mealFoodExtService.lambdaUpdate().in(MealFoodExt::getRelatedId, primaryKeys).remove();
    }

    @Override
    public List<FoodInfoEntity> getRecipesFood(String recipesId) {
        return baseMapper.getRecipesFood(recipesId);
    }

    @Override
    public List<FoodInfoEntity> getNormalDiseaseFood(List<String> diseaseId) {
        return baseMapper.getNormalDiseaseFood(diseaseId);
    }

    @Override
    public List<FoodInfoEntity> getDiseaseFood(List<String> diseaseId, int forbiddenOrRecommend) {
        return baseMapper.getDiseaseFoodAll(diseaseId, forbiddenOrRecommend);
    }

    @Override
    public List<FoodInfoEntity> getCurrentDiseaseFood(List<String> diseaseId, LocalDate date, LocalTime startTime, LocalTime endTime, int forbiddenOrRecommend) {
        return baseMapper.getCurrentDiseaseFoodAll(diseaseId, startTime, endTime, date, forbiddenOrRecommend);
    }

    @Override
    public List<FoodInfoEntity> getCurrentNormalFood(List<String> diseaseId, LocalDate date, LocalTime startTime, LocalTime endTime) {
        return baseMapper.getCurrentNormalFoodAll(diseaseId, startTime, endTime, date);
    }

    @Override
    public List<FoodInfoEntity> getCurrentFoodAll(LocalDate date, LocalTime startTime, LocalTime endTime) {
        return baseMapper.getCurrentFoodAll(startTime, endTime, date);
    }

    @Override
    public List<FoodInfoEntity> getMealTurnFood(String mealWeekId, String mealTurn) {
        return baseMapper.getMealTurnFood(mealWeekId, mealTurn);
    }

    @Override
    public List<FoodInfoEntity> getWeekFoodAll(LocalDate date) {
        return baseMapper.getWeekFoodAll(date);
    }

    @Override
    public List<String> getMealTurnFoodId(String mealId, String mealTurn) {
        return baseMapper.getMealTurnFoodId(mealId, mealTurn);
    }

}
